using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Linq;

namespace yyyy.cccc.zzzz.framework
{

    class SelectedInfo
    {
        public string searchText;
        public object fieldValue;
        public object fieldInfo;
        public object obj;

        public System.Type showType;

        public System.Type GetFieldType()
        {
            var a = fieldInfo as System.Reflection.FieldInfo;
            if (a != null)
            {
                return a.FieldType;
            }

            var b = fieldInfo as System.Reflection.PropertyInfo;
            if (b != null)
            {
                return b.PropertyType;
            }

            return null;
        }

        public System.Type GetValueType()
        {
            if (fieldValue != null)
            {
                return fieldValue.GetType();
            }

            return GetFieldType();
        }

        public string GetFieldName()
        {
            var a = fieldInfo as System.Reflection.FieldInfo;
            if (a != null)
            {
                return a.Name;
            }

            var b = fieldInfo as System.Reflection.PropertyInfo;
            if (b != null)
            {
                return b.Name;
            }

            return null;
        }
    }

    //show array, Ilist, Idictionary, hashset, hashtable...texture


    enum SearchMode
    {
        assembly,
        scene,
        resource,
        assetbundle,
    }

    public class InspectDataView
    {
        List<object> selectedObjs = new List<object>();

        Vector2 scrollViewPos;
        string searchTextInternal { get; set; }
        public string searchText { get; set; }

        bool publicMemberOnly = false;

        bool showMethods;

        // HashSet<System.Type> baseTypeSet = new HashSet<System.Type>(){typeof(System.Int16), 
        //                                                             typeof(System.Int32), 
        //                                                             typeof(System.Int64), 
        //                                                             typeof(System.UInt16), 
        //                                                             typeof(System.UInt32), 
        //                                                             typeof(System.UInt64),
        //                                                             typeof(System.Byte),
        //                                                             typeof(System.SByte),
        //                                                             typeof(System.Char),
        //                                                             typeof(System.Boolean),
        //                                                             typeof(System.String),
        //                                                             typeof(System.Single),
        //                                                             typeof(System.Double),
        //                                                             typeof(System.UIntPtr),
        //                                                             typeof(System.IntPtr),

        //                                                             };

        // Dictionary<System.Type, System.Func<object, string>> showSimpleValueTypeSet = new Dictionary<System.Type, System.Func<object, string>>{
        //                                                             {typeof(UnityEngine.Vector2), ToString},
        //                                                             {typeof(UnityEngine.Vector3), ToString},
        //                                                             {typeof(UnityEngine.Vector4), ToString},
        //                                                             {typeof(UnityEngine.Vector2Int), ToString},
        //                                                             {typeof(UnityEngine.Vector3Int), ToString},
        //                                                             {typeof(UnityEngine.Quaternion), ToString},
        //                                                             {typeof(UnityEngine.Rect), ToString},
        //                                                             {typeof(UnityEngine.RectInt), ToString},
        //                                                             {typeof(UnityEngine.RectOffset), ToString},
        //                                                             };

        Dictionary<System.Type, System.Func<object, string>> showValueTypeSet = new Dictionary<System.Type, System.Func<object, string>>(){{typeof(System.Exception), ToExceptionMessage},
                                                                                                                                        {typeof(KeyValuePair<,>), KeyValueToString},

                                                                                                                                        {typeof(System.Type), TypeToString},};

        int pageIndex = 0;
        public int maxPageItemNum = 500;

        public System.Action keyboardBtnCallback;



        // Dictionary<System.Type, System.Func<object, string>> simpleTypeStrFuncMap = new Dictionary<System.Type, System.Func<object, string>>(){{typeof(UnityEngine.Vector3), (object b) =>
        // {
        //     Vector3 a = (Vector3)b;
        //     return string.Format("({0}, {1}, {2})", a.x, a.y, a.z);
        // }
        // }};




        UnityEngine.SceneManagement.Scene dontDestroyOnLoadScene;

        bool inited;
        public bool enableMaxWidth { get; set; }
        public void Init()
        {
            if (inited)
            {
                return;
            }
            inited = false;

            var go = new GameObject("DontDestroyOnLoad Object");
            GameObject.DontDestroyOnLoad(go);
            dontDestroyOnLoadScene = go.scene;
            GameObject.Destroy(go);
        }

        static string KeyValueToString(object b)
        {
            var keyProInfo = b.GetType().GetProperty("Key");
            var valProInfo = b.GetType().GetProperty("Value");
            return keyProInfo.GetValue(b).ToString() + "->" + valProInfo.GetValue(b).ToString();
        }

        static string ToString(object b)
        {
            return b.ToString();
        }

        static string TypeToString(object b)
        {
            if (b != null)
            {
                return b.ToString();
            }

            return "null";
        }

        static string ToExceptionMessage(object b)
        {
            if (b == null)
            {
                return "null";
            }

            return ((System.Exception)b).Message;
        }

        string GetShowTypeName(object a, System.Type showType = null)
        {
            var d = a as SelectedInfo;
            if (d != null)
            {
                if (d.GetFieldType() != null)
                {
                    // string b = GetShowTypeName(d.GetFieldType(), out outName);

                    // var value = d.fieldValue?.ToString();
                    return "->" + d.GetFieldName() + " | " + GetShowTypeName(d.fieldValue, d.GetFieldType());
                }
                else
                {

                    // if(d.showType == null)
                    // {
                    //     return null;
                    // }
                    // else
                    {
                        // if(d.fieldValue != null)
                        {
                            // string ret = GetShowTypeName(d.fieldValue, out outName);
                            // outName = GetTypeFullName(d.showType);
                            // return ret;

                            // return "object: " + d.fieldValue.ToString() + " | type:" + GetTypeFullName(d.showType);
                            return GetShowTypeName(d.fieldValue, d.showType);

                            // return "instace(" + GetTypeFullName(d.showType) + ")";
                        }

                        // // outName = GetTypeFullName(d.showType);
                        // // return "type: ";

                        // return "type: " + GetTypeFullName(d.showType);
                    }
                }
            }
            else
            {
                // if(a is UnityEngine.SceneManagement.Scene)
                // {
                //     outName = ((UnityEngine.SceneManagement.Scene)a).name;
                //     return "scene";
                // }
                // else

                if (a != null)
                {
                    // if(a is System.Type)
                    // {
                    //     var c = a as System.Type;

                    //     string typeType = null;
                    //     if(c.IsEnum)
                    //     {
                    //         typeType = "enum";
                    //     }
                    //     else
                    //     {
                    //         if(c.IsValueType)
                    //         {
                    //             typeType = "valueType";
                    //         }
                    //         else if(c.IsClass)
                    //         {
                    //             typeType = "class";
                    //         }
                    //         else if(c.IsInterface)
                    //         {
                    //             typeType = "interface";
                    //         }
                    //         else if(c.IsArray)
                    //         {
                    //             typeType = "array";
                    //         }
                    //         else if(c.IsSubclassOf(typeof(System.Delegate)))
                    //         {
                    //             typeType = "delegate";
                    //         }
                    //         else
                    //         {
                    //             typeType = "unknown type";
                    //         }
                    //     }

                    //     return "type: " + typeType + ": " + GetTypeFullName(c) + " | type:" + GetTypeFullName(showType??a.GetType());;
                    // }
                    // else
                    {
                        string objTypeName = "object";
                        if (a is UnityEngine.Object)
                        {
                            var uniObj = a as UnityEngine.Object;
                            string unityObjName = "";
                            unityObjName = uniObj.name;
                            string unityTypeName = "unity_object";
                            if (a is UnityEngine.Component)
                            {
                                unityTypeName = "unity_component";
                            }
                            else if (a is UnityEngine.GameObject)
                            {
                                unityTypeName = "unity_gameobj";
                            }

                            objTypeName = unityTypeName + "(" + unityObjName + "," + uniObj.GetInstanceID() + ")";
                        }
                        else if (a is UnityEngine.SceneManagement.Scene)
                        {
                            string unityObjName = "";
                            unityObjName = ((UnityEngine.SceneManagement.Scene)a).name;
                            objTypeName = "unity_scene(" + unityObjName + ")";
                        }
                        else if (a is System.Type)
                        {
                            objTypeName = "type_object";
                        }

                        return objTypeName + ":" + a.ToString() + " | type:" + GetTypeFullName(showType ?? a.GetType());

                        // string objName = null;
                        // if(a is UnityEngine.Object)
                        // {
                        //     var gameobj = a as UnityEngine.Object;
                        //     objName = gameobj.name;
                        // }
                        // else if(a is UnityEngine.SceneManagement.Scene)
                        // {
                        //     var s = (UnityEngine.SceneManagement.Scene)a;
                        //     objName = s.name;
                        // }

                        // // if()
                        // // {
                        // //     outName = gameobj.name;
                        // //     return "unity_object()";
                        // // }
                        // // else
                        // {
                        //     outName = GetTypeFullName(a.GetType());
                        //     string temp = null;
                        //     return ((objName != null? objName: "") + " | object") + "(" + GetShowTypeName(a.GetType(), out temp) + ")";
                        // }
                    }
                }
                else
                {
                    if (showType == null)
                    {
                        return "null";
                    }

                    var c = showType;

                    string typeType = null;
                    if (c.IsEnum)
                    {
                        typeType = "enum";
                    }
                    else
                    {
                        if (c.IsValueType)
                        {
                            typeType = "valueType";
                        }
                        else if (c.IsClass)
                        {
                            typeType = "class";
                        }
                        else if (c.IsInterface)
                        {
                            typeType = "interface";
                        }
                        else if (c.IsArray)
                        {
                            typeType = "array";
                        }
                        else if (c.IsSubclassOf(typeof(System.Delegate)))
                        {
                            typeType = "delegate";
                        }
                        else
                        {
                            typeType = "unknown type";
                        }
                    }

                    return typeType + ": " + GetTypeFullName(c);
                }
            }
        }

        public void ShowGUI()
        {
            var oldButtonTextAlignment = GUI.skin.button.alignment;
            GUI.skin.button.alignment = TextAnchor.MiddleLeft;

            try
            {
                Show();
            }
            catch (System.Exception e)
            {
                Debug.LogException(e);
            }

            GUI.skin.button.alignment = oldButtonTextAlignment;
        }


        // bool layoutChanged = false;



        void Show()
        {
            if (Event.current.type == EventType.Layout)
            {
                if (searchText != searchTextInternal)
                {
                    searchTextInternal = searchText;
                    pageIndex = 0;

                    // layoutChanged = true;
                }
            }

            // if(layoutChanged && Event.current.type == EventType.Repaint)
            // {
            //     layoutChanged = false;
            //     return;
            // }

            GUILayout.BeginVertical(enableMaxWidth ? GUILayout.MaxWidth(Screen.width) : GUILayout.ExpandWidth(true));
            // GUILayout.BeginVertical();


            GUILayout.BeginHorizontal();


            // if(keyboardBtnCallback != null)
            // {
            //     if(GUILayout.Button("search:", GUILayout.ExpandWidth(false)))
            //     {
            //         keyboardBtnCallback();   
            //     }
            // }
            // else
            {
                GUILayout.Label("search:", GUILayout.ExpandWidth(false));
            }

            if (keyboardBtnCallback != null)
            {
                if (GUILayout.Button(string.IsNullOrEmpty(searchTextInternal) ? "click here to input" : searchTextInternal, GUILayout.MinWidth(Screen.width * 0.3f)))
                {
                    keyboardBtnCallback();
                }
            }
            else
            {
                searchText = GUILayout.TextField(searchTextInternal, GUILayout.MinWidth(Screen.width * 0.3f));

                // newSearchText = GUILayout.TextField(searchText);

                // if(newSearchText != searchText)
                // {
                //     searchText = newSearchText;
                //     pageIndex = 0;

                //     // layoutChanged = true;
                // }
            }



            // publicMemberOnly = GUILayout.Toggle(publicMemberOnly, "only public member", GUILayout.ExpandWidth(false));
            GUILayout.EndHorizontal();




            scrollViewPos = GUILayout.BeginScrollView(scrollViewPos);
            GUILayout.BeginVertical();

            // if(selectedObjs.Count > 0)
            {
                Title("selected objects(" + selectedObjs.Count + "):");
            }

            for (int i = 0; i < selectedObjs.Count; i++)
            {
                var a = GetSelectedObj(i);

                FontStyle oldFontStyle = GUI.skin.button.fontStyle;
                if (i == selectedObjs.Count - 1)
                {
                    GUI.skin.button.fontStyle = FontStyle.Bold;
                }

                try
                {
                    string btnText = null;
                    if (i == 0)
                    {
                        btnText = "search mode: " + a.fieldValue;
                    }
                    else
                    {

                        SearchMode searchMode = (SearchMode)GetSelectedObj(0).fieldValue;
                        if (i == 1 && searchMode == SearchMode.assembly)
                        {
                            {
                                var b = a.fieldValue as System.Reflection.Assembly;
                                btnText = "assembly: " + b.GetName().Name;

                            }
                        }
                        else
                        {
                            string typeName = GetShowTypeName(a);
                            btnText = typeName;


                        }
                    }


                    if (GUILayout.Button(btnText))
                    {
                        if (i == selectedObjs.Count - 1)
                        {
                            searchText = (selectedObjs[i] as SelectedInfo).searchText;
                            selectedObjs.RemoveRange(i, selectedObjs.Count - i);
                        }
                        else
                        {
                            searchText = (selectedObjs[i + 1] as SelectedInfo).searchText;
                            selectedObjs.RemoveRange(i + 1, selectedObjs.Count - i - 1);
                        }

                        // newSearchText = null;
                        pageIndex = 0;
                        break;
                    }
                }
                catch (System.Exception e)
                {
                    throw e;
                }
                finally
                {
                    GUI.skin.button.fontStyle = oldFontStyle;
                }
            };


            GUILayout.Label("");
            GUILayout.Label("---------data info----------");

            if (selectedObjs.Count <= 0)
            {
                Title("search modes:");

                var searchModes = System.Enum.GetNames(typeof(SearchMode));

                for (int i = 0; i < searchModes.Length; i++)
                {
                    var mode = System.Enum.Parse(typeof(SearchMode), searchModes[i]);
                    if (GUILayout.Button(mode.ToString()))
                    {
                        PushSelectedObj(mode);

                        break;
                    }
                }
            }
            else if (selectedObjs.Count == 1)
            {
                switch ((SearchMode)GetSelectedObj(0).fieldValue)
                {
                    case SearchMode.assembly:
                        {
                            System.Reflection.Assembly[] assemblies = System.AppDomain.CurrentDomain.GetAssemblies();

                            if (!string.IsNullOrEmpty(searchTextInternal))
                            {
                                assemblies = System.Array.FindAll(assemblies, (a) => a.GetName().Name.ToLower().Contains(searchTextInternal.ToLower()));
                            }

                            Title(string.Format("assemblies({0}):", assemblies.Length));
                            for (int i = 0; i < assemblies.Length; i++)
                            {
                                var assembly = assemblies[i];
                                if (GUILayout.Button(assembly.GetName().Name))
                                {
                                    PushSelectedObj(assembly);

                                    break;
                                }
                            }
                        }
                        break;
                    case SearchMode.scene:
                        {
                            Title("scenes:");
                            List<UnityEngine.SceneManagement.Scene> scenes = new List<UnityEngine.SceneManagement.Scene>();
                            for (int i = 0; i < UnityEngine.SceneManagement.SceneManager.sceneCount; i++)
                            {
                                var scene = UnityEngine.SceneManagement.SceneManager.GetSceneAt(i);
                                scenes.Add(scene);
                            }

                            if (dontDestroyOnLoadScene.rootCount > 0)
                            {
                                scenes.Add(dontDestroyOnLoadScene);
                            }

                            if (!string.IsNullOrEmpty(searchTextInternal))
                            {
                                scenes = scenes.FindAll((a) => a.name.ToLower().Contains(searchTextInternal.ToLower()));
                            }

                            scenes.ForEach((scene) =>
                            {
                                if (GUILayout.Button(scene.name))
                                {
                                    PushSelectedObj(scene);
                                }
                            });
                        }
                        break;
                    case SearchMode.resource:
                        {
                            var resObjs = Resources.FindObjectsOfTypeAll<UnityEngine.Object>();

                            if (!string.IsNullOrEmpty(searchTextInternal))
                            {
                                resObjs = System.Array.FindAll(resObjs, (a) => a.name.ToLower().Contains(searchTextInternal.ToLower()) || a.GetType().ToString().ToLower().Contains(searchTextInternal.ToLower()));
                            }


                            int beginItemIndex = pageIndex * maxPageItemNum;
                            int endItemIndex = Mathf.Min((pageIndex + 1) * maxPageItemNum, resObjs.Length);

                            GUILayout.BeginHorizontal();
                            Title(string.Format("resources({0}):", resObjs.Length));
                            if (GUILayout.Button("[" + beginItemIndex + "-" + endItemIndex + "]", GUILayout.ExpandWidth(false)))
                            {
                                int pageNum = (resObjs.Length / maxPageItemNum);
                                if (resObjs.Length % maxPageItemNum != 0)
                                {
                                    pageNum++;
                                }

                                pageIndex++;
                                pageIndex %= pageNum;
                            }
                            GUILayout.EndHorizontal();


                            for (int i = pageIndex * maxPageItemNum; i < (pageIndex + 1) * maxPageItemNum && i < resObjs.Length; i++)
                            {
                                var res = resObjs[i];
                                if (GUILayout.Button(res.name + " | " + res.GetType()))
                                {
                                    // SelectedInfo info = new SelectedInfo();
                                    // info.fieldValue = res;
                                    // info.showType = res.GetType();
                                    // PushSelectedObj(info);

                                    PushSelectedObj(res);

                                    break;
                                }
                            }

                            // Title(string.Format("resources({0}):", resObjs.Length));
                            // for(int i = 0; i < resObjs.Length; i++)
                            // {
                            //     var res = resObjs[i];
                            //     if(GUILayout.Button(res.name + " | " + res.GetType()))
                            //     {
                            //         SelectedInfo info = new SelectedInfo();
                            //         info.fieldValue = res;
                            //         info.showType = res.GetType();
                            //         PushSelectedObj(info);
                            //         newSearchText = null;
                            //         break;
                            //     }
                            // }
                        }
                        break;
                    case SearchMode.assetbundle:
                        {
                            var allab = AssetBundle.GetAllLoadedAssetBundles();
                            List<AssetBundle> abList = new List<AssetBundle>();
                            foreach (var b in allab)
                            {
                                abList.Add(b);
                            }

                            if (!string.IsNullOrEmpty(searchTextInternal))
                            {
                                abList = abList.FindAll((a) => a.name.ToLower().Contains(searchTextInternal.ToLower()));
                            }

                            Title(string.Format("assetbundles({0}):", abList.Count));
                            for (int i = 0; i < abList.Count; i++)
                            {
                                var res = abList[i];
                                if (GUILayout.Button(res.name + " | " + res.isStreamedSceneAssetBundle))
                                {
                                    // SelectedInfo info = new SelectedInfo();
                                    // info.fieldValue = res;
                                    // info.showType = res.GetType();
                                    // PushSelectedObj(info);

                                    PushSelectedObj(res);
                                    break;
                                }
                            }
                        }
                        break;
                }
            }
            else
            {
                if (selectedObjs.Count == 2 && (SearchMode)(GetSelectedObj(0).fieldValue) == SearchMode.assembly)
                {
                    var selectedAssembly = GetSelectedObj(selectedObjs.Count - 1).fieldValue as System.Reflection.Assembly;
                    if (selectedAssembly != null)
                    {
                        System.Type[] types = selectedAssembly.GetTypes();

                        if (!string.IsNullOrEmpty(searchTextInternal))
                        {
                            types = System.Array.FindAll(types, (a) => GetTypeFullName(a).ToLower().Contains(searchTextInternal.ToLower()));
                        }


                        // System.Array.Sort<System.Type>(types, (a, b) => {return string.Compare(a.FullName, b.FullName); });

                        int beginItemIndex = pageIndex * maxPageItemNum;
                        int endItemIndex = Mathf.Min((pageIndex + 1) * maxPageItemNum, types.Length);

                        GUILayout.BeginHorizontal();
                        Title(string.Format("types({0}):", types.Length));
                        if (GUILayout.Button("[" + beginItemIndex + "-" + endItemIndex + "]", GUILayout.ExpandWidth(false)))
                        {
                            int pageNum = (types.Length / maxPageItemNum);
                            if (types.Length % maxPageItemNum != 0)
                            {
                                pageNum++;
                            }

                            pageIndex++;
                            pageIndex %= pageNum;
                        }
                        GUILayout.EndHorizontal();



                        for (int i = pageIndex * maxPageItemNum; i < (pageIndex + 1) * maxPageItemNum && i < types.Length; i++)
                        {
                            var t = types[i];
                            if (GUILayout.Button(GetTypeFullName(t)))
                            {
                                PushSelectedObj(t);
                                break;
                            }
                        }
                    }
                }
                else
                {
                    var b = GetSelectedObj(selectedObjs.Count - 1) as SelectedInfo;
                    if (b != null)
                    {
                        if (b.GetFieldType() != null)
                        {
                            ShowObjectInfo(b.fieldValue, b.GetFieldType(), b.fieldInfo as System.Reflection.MemberInfo);
                        }
                        else if (b.showType != null)
                        {
                            // if(b.fieldValue != null)
                            {
                                ShowObjectInfo(b.fieldValue, b.showType);
                            }
                            // else
                            // {
                            //     ShowObjectInfo(b.showType, b.showType.GetType());
                            // }
                        }
                        else
                        {
                            ShowObjectInfo(null, null);
                        }
                    }
                    // else
                    // {
                    //     var t = GetSelectedObj(selectedObjs.Count - 1).fieldValue;
                    //     if(t is System.Type)
                    //     {
                    //         ShowObjectInfo(null, t as System.Type);
                    //     }
                    //     else
                    //     {
                    //         ShowObjectInfo(t, t.GetType());
                    //     }
                    // }
                }
            }


            GUILayout.EndVertical();
            GUILayout.EndScrollView();



            GUILayout.EndVertical();
        }


        void ShowObjectInfo(object obj, System.Type objType, System.Reflection.MemberInfo memberInfo = null)
        {
            if (memberInfo != null)
            {
                GUILayout.BeginHorizontal();
                Title("member info:");
                if (GUILayout.Button(memberInfo.ToString() + " | " + memberInfo.GetType()))
                {
                    this.PushSelectedObj(memberInfo);
                }
                GUILayout.EndHorizontal();
            }


            GUILayout.Label("");
            if (objType == null)
            {
                GUILayout.Label("type: null");
                return;
            }

            // if(obj is System.Type)
            // {
            //     var tt = obj as System.Type;

            //     Title("type:");
            //     if(GUILayout.Button(GetTypeFullName(tt)))
            //     {
            //         SelectedInfo info = new SelectedInfo();
            //         info.showType = tt;
            //         this.PushSelectedObj(info);
            //         newSearchText = null;
            //     }


            //     GUILayout.Label("");
            //     Title("static members: ");
            //     ShowTypeFields(tt, null, false);
            //     GUILayout.Label("");
            //     Title("instance members: ");
            //     ShowTypeFields(tt, null, true);
            // }
            // else
            {
                // GUILayout.BeginHorizontal();
                // Title("show type data:");
                // if(GUILayout.Button(GetTypeFullName(objType)))
                // {
                //     SelectedInfo info = new SelectedInfo();
                //     info.showType = objType;
                //     this.PushSelectedObj(info);
                //     newSearchText = null;
                // }
                // GUILayout.EndHorizontal();


                // if(obj != null && objType != obj.GetType())
                // {
                //     GUILayout.BeginHorizontal();
                //     Title("convert to real type:");
                //     if(GUILayout.Button(GetTypeFullName(obj.GetType())))
                //     {
                //         this.PushSelectedObj(obj);
                //         newSearchText = null;
                //     }
                //     GUILayout.EndHorizontal();
                // }

                // if(obj != null && objType.BaseType != null)
                // {
                //     GUILayout.BeginHorizontal();
                //     Title("convert to base type:");
                //     if(GUILayout.Button(GetTypeFullName(objType.BaseType)))
                //     {
                //         SelectedInfo info = new SelectedInfo();
                //         info.fieldValue = obj;
                //         info.showType = objType.BaseType;
                //         this.PushSelectedObj(info);
                //         newSearchText = null;
                //     }
                //     GUILayout.EndHorizontal();
                // }

                System.Type tempObjType = objType;
                if (obj != null)
                {
                    tempObjType = obj.GetType();
                }

                var tempObjType2 = tempObjType;
                {
                    Title("types:");
                    while (tempObjType2 != null)
                    {
                        GUILayout.BeginHorizontal();
                        if (tempObjType2 == objType)
                        {
                            GUILayout.Label("current type:", GUILayout.ExpandWidth(false));
                            if (GUILayout.Button(GetTypeFullName(objType)))
                            {
                                SelectedInfo info = new SelectedInfo();
                                info.fieldValue = objType;
                                info.showType = objType.GetType();
                                this.PushSelectedObj(info);
                            }
                        }
                        else
                        {
                            if (obj != null)
                            {
                                GUILayout.Label("convert to:", GUILayout.ExpandWidth(false));
                            }
                            else
                            {
                                GUILayout.Label("base type:", GUILayout.ExpandWidth(false));
                            }

                            if (GUILayout.Button(GetTypeFullName(tempObjType2)))
                            {
                                if (obj != null)
                                {
                                    SelectedInfo info = new SelectedInfo();
                                    info.fieldValue = obj;
                                    info.showType = tempObjType2;
                                    this.PushSelectedObj(info);
                                }
                                else
                                {
                                    PushSelectedObj(tempObjType2);
                                }
                            }
                        }

                        GUILayout.EndHorizontal();

                        tempObjType2 = tempObjType2.BaseType;
                    }

                    // if(typeof(System.Reflection.ICustomAttributeProvider).IsAssignableFrom(tempObjType))
                    // {
                    //     // var tempTypeObj = obj as System.Reflection.ICustomAttributeProvider;
                    //     // var e = tempTypeObj.GetCustomAttributes(true);

                    //     // if(e.Length > 0)
                    //     // {
                    //     //     GUILayout.Label("");
                    //     //     Title(string.Format("CustomAttributes:"));
                    //     //     foreach(var ee in e)
                    //     //     {
                    //     //         if(GUILayout.Button((ee.ToString())))
                    //     //         {
                    //     //             PushSelectedObj(ee);
                    //     //             newSearchText = null;
                    //     //         }
                    //     //     }
                    //     // }

                    //     var tempTypeObj = tempObjType as System.Reflection.ICustomAttributeProvider;
                    //     var e = tempTypeObj.GetCustomAttributes(true);

                    //     // if(e.Length > 0)
                    //     {
                    //         GUILayout.Label("");
                    //         Title(string.Format("CustomAttributes:"));
                    //         foreach(var ee in e)
                    //         {
                    //             if(GUILayout.Button((ee.ToString())))
                    //             {
                    //                 PushSelectedObj(ee);
                    //                 newSearchText = null;
                    //             }
                    //         }
                    //     }
                    // }

                    if (obj != null && typeof(System.Reflection.ICustomAttributeProvider).IsAssignableFrom(tempObjType))
                    {
                        var tempTypeObj = obj as System.Reflection.ICustomAttributeProvider;
                        var e = tempTypeObj.GetCustomAttributes(true);

                        if (e.Length > 0)
                        {
                            GUILayout.Label("");
                            Title(string.Format("CustomAttributes:"));
                            foreach (var ee in e)
                            {
                                if (GUILayout.Button((ee.ToString())))
                                {
                                    PushSelectedObj(ee);
                                }
                            }
                        }

                        // var tempTypeObj = tempObjType as System.Reflection.ICustomAttributeProvider;
                        // var e = tempTypeObj.GetCustomAttributes(true);

                        // // if(e.Length > 0)
                        // {
                        //     GUILayout.Label("");
                        //     Title(string.Format("CustomAttributes:"));
                        //     foreach(var ee in e)
                        //     {
                        //         if(GUILayout.Button((ee.ToString())))
                        //         {
                        //             PushSelectedObj(ee);
                        //             newSearchText = null;
                        //         }
                        //     }
                        // }
                    }
                }



                if (obj is System.Type)
                {
                    var tempTypeObj = obj as System.Type;

                    var interfaces = tempTypeObj.GetInterfaces();


                    if (interfaces.Length > 0)
                    {
                        GUILayout.Label("");
                        Title(string.Format("Interfaces:"));
                        foreach (var ee in interfaces)
                        {
                            if (GUILayout.Button(GetTypeFullName(ee)))
                            {
                                PushSelectedObj(ee);
                            }
                        }
                    }

                    {
                        var gta = tempTypeObj.GetNestedTypes();
                        if (gta.Length > 0)
                        {
                            GUILayout.Label("");
                            Title(string.Format("NestedTypes:"));
                            for (int i = 0; i < gta.Length; i++)
                            {
                                if (GUILayout.Button(GetTypeFullName(gta[i])))
                                {
                                    PushSelectedObj(gta[i]);
                                }
                            }
                        }
                    }
                }
                else if (obj is UnityEngine.SceneManagement.Scene)
                {
                    var scene = (UnityEngine.SceneManagement.Scene)obj;
                    var objs = scene.GetRootGameObjects();

                    if (!string.IsNullOrEmpty(searchTextInternal))
                    {
                        objs = System.Array.FindAll(objs, (a) => a.name.ToLower().Contains(searchTextInternal.ToLower()));
                    }


                    GUILayout.Label("");
                    Title("GameObjects: ");
                    System.Array.ForEach(objs, (a) =>
                    {
                        if (GUILayout.Button(a.name))
                        {
                            PushSelectedObj(a);
                        }
                    });
                }
                else if (obj is GameObject)
                {
                    var o = obj as GameObject;
                    GUILayout.Label("");
                    Title("components: ");
                    var coms = o.GetComponents<UnityEngine.Component>();

                    if (!string.IsNullOrEmpty(searchTextInternal))
                    {
                        coms = System.Array.FindAll(coms, (a) => GetTypeFullName(a.GetType()).ToLower().Contains(searchTextInternal.ToLower()));
                    }

                    System.Array.ForEach(coms, (a) =>
                    {
                        if (GUILayout.Button(GetTypeFullName(a.GetType())))
                        {
                            PushSelectedObj(a);
                        }
                    });

                    GUILayout.Label("");
                    Title("child GameObjects: ");

                    List<GameObject> childs = new List<GameObject>();
                    for (int i = 0; i < o.transform.childCount; i++)
                    {
                        var t = o.transform.GetChild(i);
                        childs.Add(t.gameObject);
                    }

                    if (!string.IsNullOrEmpty(searchTextInternal))
                    {
                        childs = childs.FindAll((a) => GetTypeFullName(a.GetType()).ToLower().Contains(searchTextInternal.ToLower()));
                    }

                    for (int i = 0; i < childs.Count; i++)
                    {
                        var t = childs[i];

                        if (GUILayout.Button(t.name))
                        {
                            PushSelectedObj(t.gameObject);
                        }
                    }
                }
                else if (obj is Material)
                {
                    var mat = obj as Material;
                    var keywords = mat.shaderKeywords;
                    if (keywords.Length > 0)
                    {
                        GUILayout.Label("");
                        Title("keywords: ");
                        foreach (var kw in keywords)
                        {
                            GUILayout.Label(kw + ": " + mat.IsKeywordEnabled(kw));
                        }
                    }

                    var proNames = mat.GetTexturePropertyNames();
                    if (proNames.Length > 0)
                    {
                        GUILayout.Label("");
                        Title("textures: ");
                        foreach (var pn in proNames)
                        {
                            var tex = mat.GetTexture(pn);
                            if (tex != null)
                            {
                                if (GUILayout.Button(pn + ": " + tex))
                                {
                                    PushSelectedObj(tex);
                                }
                            }
                            else
                            {
                                GUILayout.Label(pn);
                            }
                        }
                    }
                }
                else if (obj is Texture2D)
                {
                    var tex = obj as Texture2D;
                    GUILayout.Label("");
                    Title("preview:");

                    int width = 300;
                    var ss = GUI.skin.box.normal.background;
                    GUI.skin.box.normal.background = tex;
                    GUILayout.Box("", GUILayout.Width(width), GUILayout.Height(width / ((float)tex.width / tex.height)));
                    GUI.skin.box.normal.background = ss;

                }
                else if (obj is AssetBundle)
                {
                    var ab = obj as AssetBundle;

                    GUILayout.Label("");
                    if (GUILayout.Button("show asset paths"))
                    {
                        if (ab.isStreamedSceneAssetBundle)
                        {
                            PushSelectedObj(ab.GetAllScenePaths());
                        }
                        else
                        {
                            PushSelectedObj(ab.GetAllAssetNames());
                        }
                    }
                }
                else if (obj is System.Reflection.MethodBase)
                {
                    var m = obj as System.Reflection.MethodBase;

                    if (m.GetMethodBody() != null)
                    {
                        GUILayout.Label("");
                        if (GUILayout.Button("method body"))
                        {
                            this.PushSelectedObj(m.GetMethodBody());
                        }
                    }
                }



                // if(baseTypeSet.Contains(objType))
                // {
                //     GUILayout.Label(obj.ToString());
                // }
                // else
                {
                    if (obj != null)
                    {
                        // if(objType.IsGenericType && objType.GetGenericTypeDefinition() == typeof(List<>))
                        if (typeof(ICollection).IsAssignableFrom(objType) && typeof(IEnumerable).IsAssignableFrom(objType) && !typeof(IDictionary).IsAssignableFrom(objType))
                        {
                            GUILayout.Label("");
                            Title(string.Format("elements({0}):", (obj as ICollection).Count));
                            int index = 0;
                            foreach (var item in obj as IEnumerable)
                            {
                                ShowIndexValue(index, item);
                                index++;
                            }
                        }
                        else
                        {
                            bool implementICollection = objType.GetInterfaces().Any(x => x.IsGenericType && x.GetGenericTypeDefinition() == typeof(ICollection<>));

                            if (implementICollection)
                            {
                                GUILayout.Label("");
                                Title(string.Format("elements:"));
                                foreach (var item in obj as IEnumerable)
                                {
                                    ShowIndexValue(-1, item);
                                }
                            }
                        }

                        if (objType.IsSubclassOf(typeof(System.MulticastDelegate)))
                        {
                            var tempDelegate = obj as System.MulticastDelegate;
                            var tempDelegates = tempDelegate.GetInvocationList();

                            GUILayout.Label("");
                            Title(string.Format("InvocationList{0}:", tempDelegates.Length));
                            for (int i = 0; i < tempDelegates.Length; i++)
                            {
                                ShowIndexValue(i, tempDelegates[i]);
                            }
                        }
                    }


                    GUILayout.Label("");
                    Title("instance members: ");
                    ShowTypeFields(objType, obj, true);
                    GUILayout.Label("");
                    Title("static members: ");
                    ShowTypeFields(objType, null, false);


                    GUILayout.Label("----------------------------------------");
                    GUILayout.Label("");
                    if (GUILayout.Button("show methods: " + showMethods))
                    {
                        showMethods = !showMethods;
                    }

                    if (showMethods)
                    {
                        GUILayout.Label("");
                        Title("instance methods: ");
                        ShowTypeMethods(objType, obj, true);
                        GUILayout.Label("");
                        Title("static methods: ");
                        ShowTypeMethods(objType, null, false);
                    }
                }
            }
        }

        void Title(string title)
        {
            var oldStyle = GUI.skin.label.fontStyle;
            var oldColor = GUI.contentColor;

            GUI.skin.label.fontStyle = FontStyle.Bold;
            GUI.contentColor = Color.yellow;
            GUILayout.Label(title, GUILayout.ExpandWidth(false));

            GUI.contentColor = oldColor;
            GUI.skin.label.fontStyle = oldStyle;
        }

        string GetTypeFullName(System.Type t)
        {
            string typeName = t.FullName;
            if (typeName == null)
            {
                typeName = t.Name;
                if (typeName != null)
                {
                    typeName = t.Namespace + "." + t.Name;
                }
            }

            if (t.IsGenericType)
            {
                // if(typeName != null)
                // {
                //     int index = typeName.IndexOf("`");

                //     typeName = index > 0? typeName.Substring(0, index) + "<": typeName;
                //     var gta = t.GenericTypeArguments;
                //     for(int i = 0; i < gta.Length; i++)
                //     {
                //         typeName += GetTypeFullName(gta[i]);
                //         if(i < gta.Length - 1)
                //         {
                //             typeName += ",";
                //         }
                //     }

                //     typeName += ">";
                //     return typeName;
                // }
                // else
                // {
                //     return "?";
                // }

                return t.ToString();

            }
            else
            {
                return typeName;
            }
        }

        void PushSelectedObj(object obj)
        {
            if (!(obj is SelectedInfo))
            {
                SelectedInfo sInfo = new SelectedInfo();
                if (obj is System.Type)
                {
                    sInfo.showType = obj as System.Type;
                    obj = sInfo;
                }
                else
                {
                    sInfo.fieldValue = obj;
                    sInfo.showType = obj.GetType();
                    obj = sInfo;
                }
            }


            var selectedObj = obj as SelectedInfo;
            selectedObj.searchText = searchText;

            this.selectedObjs.Add(obj);
            searchText = null;
            pageIndex = 0;
        }

        SelectedInfo GetSelectedObj(int index)
        {
            return this.selectedObjs[index] as SelectedInfo;
        }

        void ShowIndexValue(int index, object value)
        {
            string indexStr = "";
            if (index >= 0)
            {
                indexStr = string.Format("[{0}]: ", index);
            }

            if (value == null)
            {
                GUILayout.Label(indexStr + "null");
                return;
            }

            var fieldType = value.GetType();
            string fieldTypeName = GetTypeFullName(fieldType);

            // if(baseTypeSet.Contains(fieldType))
            // {
            //     // if(fieldType.IsEnum)
            //     // {
            //     //     if(GUILayout.Button(indexStr + value + " | " + fieldTypeName))
            //     //     {
            //     //         this.PushSelectedObj(fieldType);
            //     //         newSearchText = null;
            //     //     }
            //     // }
            //     // else
            //     {
            //         GUILayout.Label(indexStr + value + " | " + fieldTypeName);
            //     }
            // }
            // else
            {
                string text = null;
                // System.Func<object, string> toStringFunc = null;
                // if(showSimpleValueTypeSet.TryGetValue(fieldType, out toStringFunc))
                // {
                //     text = indexStr + toStringFunc(value) + " | " + fieldTypeName;
                // }
                // else
                {
                    foreach (var t in showValueTypeSet)
                    {
                        if (fieldType.IsGenericType && t.Key.IsGenericTypeDefinition)
                        {
                            if (fieldType.GetGenericTypeDefinition() == t.Key)
                            {
                                text = t.Value(value);
                                break;
                            }
                        }
                        else
                        {
                            if (!t.Key.IsGenericTypeDefinition)
                            {
                                if (fieldType.IsSubclassOf(t.Key) || t.Key.IsAssignableFrom(fieldType))
                                {
                                    text = t.Value(value);
                                    break;
                                }
                            }
                        }
                    }
                }

                if (text == null)
                {
                    text = indexStr + (value ?? "null") + " | " + fieldTypeName;
                }

                if (string.IsNullOrEmpty(text))
                {
                    text = indexStr + fieldTypeName;
                }

                if (GUILayout.Button(text))
                {
                    if (value != null)
                    {
                        this.PushSelectedObj(value);
                    }
                }
            }
        }

        object GetFieldValue(object a, object obj, out bool throwException)
        {
            try
            {
                throwException = false;
                if (a is System.Reflection.FieldInfo)
                {
                    return (a as System.Reflection.FieldInfo).GetValue(obj);
                }
                else if (a is System.Reflection.PropertyInfo)
                {
                    var p = a as System.Reflection.PropertyInfo;
                    return p.GetValue(obj);
                }

                return null;
            }
            catch (System.Exception e)
            {
                throwException = true;
                return e;
            }
        }

        void ShowOneField(object fieldInfo, object obj)
        {
            bool isStatic = false;
            System.Type fieldType = null;
            string flag = GetFlag(fieldInfo);
            string fieldName = (fieldInfo as System.Reflection.MemberInfo).Name;

            if (fieldInfo is System.Reflection.FieldInfo)
            {
                var a = fieldInfo as System.Reflection.FieldInfo;
                isStatic = a.IsStatic;
                fieldType = a.FieldType;
            }
            else if (fieldInfo is System.Reflection.PropertyInfo)
            {
                var a = fieldInfo as System.Reflection.PropertyInfo;
                isStatic = a.GetGetMethod()?.IsStatic == true || a.GetSetMethod()?.IsStatic == true;
                fieldType = a.PropertyType;
            }
            else if (fieldInfo is System.Reflection.MethodBase)
            {
                var a = fieldInfo as System.Reflection.MethodBase;
                isStatic = a.IsStatic;




                // string genericParamStr = null;
                // if(a.IsGenericMethod)
                // {
                //     var b = a.GetGenericArguments();
                //     for(int i = 0; i < b.Length; i++)
                //     {
                //         b[i].FullName
                //     }
                // }

                // string str = a.ReturnType + " " + a.Name + "(";
                // var methodsParams = a.GetParameters();
                // for(int i = 0; i < methodsParams.Length; i++)
                // {
                //     str += methodsParams[i].ParameterType + " " + methodsParams[i].Name;

                //     if(i < methodsParams.Length - 1)
                //     {
                //         str += ",";
                //     }
                // }

                // str += ")";


                string str = a.ToString();
                if (GUILayout.Button(str))
                {
                    this.PushSelectedObj(a);
                }
                return;
            }





            bool throwException = false;
            object objValue = null;

            if (isStatic || obj != null)
            {
                objValue = GetFieldValue(fieldInfo, obj, out throwException);
            }

            string fieldTypeName = GetTypeFullName(fieldType);



            if (objValue is System.Exception && throwException)
            {
                var e = objValue;
                var oldColor = GUI.contentColor;
                GUI.contentColor = Color.red;
                if (GUILayout.Button(flag + GetTypeFullName(e.GetType()) + " | " + fieldName + ": " + fieldTypeName))
                {
                    this.PushSelectedObj(e);
                }
                GUI.contentColor = oldColor;
            }
            else
            {
                // if(baseTypeSet.Contains(fieldType))
                // {
                //     GUILayout.Label(flag + fieldName + ": " + (objValue??"null") + " | " + fieldTypeName); 
                // }
                // else
                {
                    string text = null;

                    if (objValue != null)
                    {
                        // System.Func<object, string> toStringFunc = null;
                        // if(showSimpleValueTypeSet.TryGetValue(fieldType, out toStringFunc))
                        // {
                        //     text = flag + fieldName + ": " + toStringFunc(objValue) + " | " + fieldTypeName;
                        // }
                        // else
                        {
                            foreach (var t in showValueTypeSet)
                            {
                                if (fieldType.IsGenericType && t.Key.IsGenericTypeDefinition)
                                {
                                    if (fieldType.GetGenericTypeDefinition() == t.Key)
                                    {
                                        text = flag + fieldName + ": " + t.Value(objValue) + " | " + fieldTypeName;
                                        break;
                                    }
                                }
                                else
                                {
                                    if (!t.Key.IsGenericTypeDefinition)
                                    {
                                        if (fieldType.IsSubclassOf(t.Key) || t.Key.IsAssignableFrom(fieldType))
                                        {
                                            text = flag + fieldName + ": " + t.Value(objValue) + " | " + fieldTypeName;
                                            break;
                                        }
                                    }
                                }
                            }
                        }
                    }

                    if (text == null)
                    {
                        text = flag + fieldName + ": " + (objValue ?? "null") + " | " + fieldTypeName;
                    }

                    if (string.IsNullOrEmpty(text))
                    {
                        text = flag + fieldName + ": " + fieldTypeName;
                    }

                    if (GUILayout.Button(text))
                    {
                        if (isStatic || obj != null)
                        {
                            SelectedInfo info = new SelectedInfo();
                            info.fieldValue = objValue;
                            info.fieldInfo = fieldInfo;
                            info.obj = obj;
                            this.PushSelectedObj(info);
                        }
                        else
                        {
                            this.PushSelectedObj(fieldType);
                        }

                    }
                }
            }
        }

        void ShowTypeFields(System.Type objType, object obj, bool forceShowInstance)
        {
            System.Reflection.FieldInfo[] fields = objType.GetFields(((obj == null && !forceShowInstance) ? System.Reflection.BindingFlags.Static : System.Reflection.BindingFlags.Instance) | System.Reflection.BindingFlags.Public | (publicMemberOnly ? System.Reflection.BindingFlags.Default : System.Reflection.BindingFlags.NonPublic));

            if (!string.IsNullOrEmpty(searchTextInternal))
            {
                fields = System.Array.FindAll(fields, (a) => a.Name.ToLower().Contains(searchTextInternal.ToLower()));
            }



            foreach (var a in fields)
            {
                bool notSupport = false;
                var customAttrs = a.GetCustomAttributes(typeof(System.ObsoleteAttribute), true);
                foreach (var c in customAttrs)
                {
                    var d = c as System.ObsoleteAttribute;
                    if (d.IsError)
                    {
                        notSupport = true;
                        break;
                    }
                }

                if (notSupport)
                {
                    continue;
                }

                ShowOneField(a, obj);


            }

            System.Reflection.PropertyInfo[] propertyInfos = objType.GetProperties(((obj == null && !forceShowInstance) ? System.Reflection.BindingFlags.Static : System.Reflection.BindingFlags.Instance) | System.Reflection.BindingFlags.Public | (publicMemberOnly ? System.Reflection.BindingFlags.Default : System.Reflection.BindingFlags.NonPublic));


            if (!string.IsNullOrEmpty(searchTextInternal))
            {
                propertyInfos = System.Array.FindAll(propertyInfos, (a) => a.Name.ToLower().Contains(searchTextInternal.ToLower()));
            }

            foreach (var a in propertyInfos)
            {
                if (obj is UnityEngine.Renderer && a.Name == "material" || a.Name == "materials")
                {
                    continue;
                }

                bool notSupport = false;
                var customAttrs = a.GetCustomAttributes(typeof(System.ObsoleteAttribute), true);
                foreach (var c in customAttrs)
                {
                    var d = c as System.ObsoleteAttribute;
                    if (d.IsError)
                    {
                        notSupport = true;
                        break;
                    }
                }

                if (notSupport)
                {
                    continue;
                }

                if (obj is System.Type)
                {
                    var t = obj as System.Type;

                    if (a.Name == "DeclaringMethod" && a.PropertyType == typeof(System.Reflection.MethodBase) && !t.IsGenericParameter)
                    {
                        var oldColor = GUI.contentColor;
                        GUI.contentColor = Color.gray;
                        GUILayout.Label("ignore " + a.Name + " " + a.PropertyType);
                        GUI.contentColor = oldColor;

                        continue;
                    }
                }



                try
                {
                    ShowOneField(a, obj);
                }
                catch (System.Exception e)
                {
                    Debug.LogException(e);
                }

            };
        }


        void ShowTypeMethods(System.Type objType, object obj, bool forceShowInstance)
        {
            var constructorInfos = objType.GetConstructors(((obj == null && !forceShowInstance) ? System.Reflection.BindingFlags.Static : System.Reflection.BindingFlags.Instance) | System.Reflection.BindingFlags.Public | (publicMemberOnly ? System.Reflection.BindingFlags.Default : System.Reflection.BindingFlags.NonPublic));

            if (!string.IsNullOrEmpty(searchTextInternal))
            {
                constructorInfos = System.Array.FindAll(constructorInfos, (a) => a.Name.ToLower().Contains(searchTextInternal.ToLower()));
            }



            foreach (var a in constructorInfos)
            {
                bool notSupport = false;
                var customAttrs = a.GetCustomAttributes(typeof(System.ObsoleteAttribute), true);
                foreach (var c in customAttrs)
                {
                    var d = c as System.ObsoleteAttribute;
                    if (d.IsError)
                    {
                        notSupport = true;
                        break;
                    }
                }

                if (notSupport)
                {
                    continue;
                }

                ShowOneField(a, obj);
            }



            var methods = objType.GetMethods(((obj == null && !forceShowInstance) ? System.Reflection.BindingFlags.Static : System.Reflection.BindingFlags.Instance) | System.Reflection.BindingFlags.Public | (publicMemberOnly ? System.Reflection.BindingFlags.Default : System.Reflection.BindingFlags.NonPublic));

            if (!string.IsNullOrEmpty(searchTextInternal))
            {
                methods = System.Array.FindAll(methods, (a) => a.Name.ToLower().Contains(searchTextInternal.ToLower()));
            }



            foreach (var a in methods)
            {
                bool notSupport = false;
                var customAttrs = a.GetCustomAttributes(typeof(System.ObsoleteAttribute), true);
                foreach (var c in customAttrs)
                {
                    var d = c as System.ObsoleteAttribute;
                    if (d.IsError)
                    {
                        notSupport = true;
                        break;
                    }
                }

                if (notSupport)
                {
                    continue;
                }

                ShowOneField(a, obj);
            }

            // System.Reflection.PropertyInfo[] propertyInfos = objType.GetProperties(((obj == null && !forceShowInstance)? System.Reflection.BindingFlags.Static: System.Reflection.BindingFlags.Instance) | System.Reflection.BindingFlags.Public | (publicMemberOnly? System.Reflection.BindingFlags.Default: System.Reflection.BindingFlags.NonPublic));


            // if(!string.IsNullOrEmpty(searchText))
            // {   
            //     propertyInfos = System.Array.FindAll(propertyInfos, (a) => a.Name.ToLower().Contains(searchText.ToLower()));
            // }

            // foreach(var a in propertyInfos)
            // {
            //     bool notSupport = false;
            //     var customAttrs = a.GetCustomAttributes(typeof(System.ObsoleteAttribute), true);
            //     foreach(var c in customAttrs)
            //     {
            //         var d = c as System.ObsoleteAttribute;
            //         if(d.IsError)
            //         {
            //             notSupport = true;
            //             break;
            //         }
            //     }

            //     if(notSupport)
            //     {
            //         continue;
            //     }

            //     if(obj is System.Type)
            //     {
            //         var t = obj as System.Type;

            //         if(a.Name == "DeclaringMethod" && a.PropertyType == typeof(System.Reflection.MethodBase) && !t.IsGenericParameter)
            //         {
            //              var oldColor = GUI.contentColor;
            //             GUI.contentColor = Color.gray;
            //             GUILayout.Label("ignore " + a.Name + " " + a.PropertyType);
            //             GUI.contentColor = oldColor;

            //             continue;
            //         }
            //     }



            //     try
            //     {
            //         ShowOneField(a, obj);
            //     }
            //     catch(System.Exception e)
            //     {
            //         Debug.LogException(e);
            //     }

            // };
        }

        string GetFlag(object fieldInfo)
        {
            string result = "";

            var a = fieldInfo as System.Reflection.FieldInfo;
            if (a != null)
            {
                // if(a.IsStatic)
                // {
                //     result += "s";
                // }

                if (a.IsPublic)
                {
                    // result += "p";
                }
                else
                {
                    result += "*";
                }
            }
            else
            {
                var b = fieldInfo as System.Reflection.PropertyInfo;
                if (b != null)
                {
                    // if(b.GetGetMethod()?.IsStatic == true || b.GetSetMethod()?.IsStatic == true)
                    // {
                    //     result += "s";
                    // }

                    if (b.GetGetMethod()?.IsPublic == true || b.GetSetMethod()?.IsPublic == true)
                    {
                        // result += "p";
                    }
                    else
                    {
                        result += "*";
                    }
                }
            }

            return result;
        }

    }

}